#ifndef _ZENTRYMANAGER_H_
#define _ZENTRYMANAGER_H_

#include <ext/hash_map>

template <typename keyT>
struct my_key_equal : public std::binary_function<keyT,keyT,bool>
{
	inline bool operator()(const keyT s1,const keyT s2) const;
};

template <>
inline bool my_key_equal<const char *>::operator()(const char *s1,const char *s2) const
{
	return 0 == strcmp(s1,s2);
}
template <>
inline bool my_key_equal<DWORD>::operator()(const DWORD s1,const DWORD s2) const
{
	return s1 == s2;
}

template <>
inline bool my_key_equal<QWORD>::operator()(const QWORD s1,const QWORD s2) const
{
	return s1 == s2;
}

/**
 *\brief 有限桶hash管理模板，非线程安全
 * key类型目前支持上面已经偏特化的char* DWORD QWORD，value类型不做限制，但要求可copy
 */
template<typename keyT,typename valueT>
class LimitHash : private zNoncopyable
{
	protected:
		typedef __gnu_cxx::hash_map<keyT,valueT,__gnu_cxx::hash<keyT>,my_key_equal<keyT> > hashmap;
		typedef hashmap::iterator iter;
		typedef hashmap::const_iterator const_iter;
		hashmap ets;

		inline bool insert(const keyT &key,valueT &value)
		{
			ets[key] = value;
			return true;
		}
		inline bool find(const keyT &key,valueT &value) const
		{
			const_iter it = ets.find(key);
			if(it != ets.end())
			{
				value = it->second;
				return true;
			}
			return false;
		}
		inline bool findOne(valueT &value) const
		{
			if(!ets.empty())
			{
				value = ets.begin()->second;
				return true;
			}
			return false;
		}

		LimitHash()
		{
		}
		~LimitHash()
		{
			clear();
		}

		inline void remove(const keyT &value)
		{
			ets.erase(key);
		}
		inline void clear()
		{
			ets.clear();
		}
		inline unsigned int size() const
		{
			return ets.size();
		}
		inline bool empty() const
		{
			return ets.empty();
		}
};

/**
 *\brief 有限桶MultiHash管理模板，非线程安全
 * key类型目前支持上面已经偏特化的char* DWORD QWORD，value类型不做限制，但要求可copy
 */
template<typename keyT,typename valueT>
class MultiHash : private zNoncopyable
{
	protected:
		typedef __gnu_cxx::hash_multimap<keyT,valueT,__gnu_cxx::hash<keyT>,my_key_equal<keyT> > hashmap;
		typedef hashmap::iterator iter;
		typedef hashmap::const_iterator const_iter;
		hashmap ets;

		inline bool insert(keyT &key,valueT &value)
		{
			ets.insert(std::make_pair(key,value));
			return true;
		}

		MultiHash()
		{
		}
		~MultiHash()
		{
			clear();
		}

		inline void clear()
		{
			ets.clear();
		}
		inline unsigned int size() const
		{
			return ets.size();
		}
		inline bool empty() const
		{
			return ets.empty();
		}
};

/**
 *\brief 以临时id为key的指针容器，需要继承使用 
 */
class zEntryTempID : public LimitHash<DWORD,zEntry *>
{
	protected:
		zEntryTempID(){}
		virtual ~zEntryTempID(){}

		inline bool push(zEntry *e)
		{
			if(e && getUniqueID(e->tempid))
			{
				zEntry *temp;
				if(!find(e->tempid,temp))
					if(insert(e->tempid,e))
						return true;
				putUniqueID(e->tempid);
			}
			return false;
		}

		inline void remove(zEntry *e)
		{
			if(e)
			{
				ptUniqueID(e->tempid);
				LimitHash<DWORD,zEntry *>::remove(e->tempid);
			}
		}

		inline zEntry * getEntryByTempID(const DWORD tempid) const
		{
			zEntry *ret = NULL;
			LimitHash<DWORD,zEntry *>::find(tempid,ret);
			return ret;
		}

		virtual bool getUniqueID(DWORD &tempid) = 0;
		virtual bool putUniqueID(const DWORD &tempid) = 0;
};

/**
 *\brief 以id为key的指针容器，需要继承使用 
 */
class zEntryID : public LimitHash<DWORD,zEntry *>
{
	protected:

		inline bool push(zEntry * &e) //point ref
		{
			zEntry *temp = NULL;
			if(!find(e->id,temp)) //not check NULL==e
				return insert(e->id,e);
			return false;
		}

		inline void remove(zEntry *e)
		{
			if(e)
			{
				LimitHash<DWORD,zEntry *>::remove(e->id);
			}
		}

		inline zEntry * getEntryByID(const DWORD id) const
		{
			zEntry *ret = NULL;
			LimitHash<DWORD,zEntry *>::find(id,ret);
			return ret;
		}
};

/**
 *\brief 以name为key的指针容器，需要继承使用 
 */
class zEntryName : public LimitHash<const char *,zEntry *>
{
	protected:

		inline bool push(zEntry * &e) //point ref
		{
			zEntry *temp = NULL;
			if(!find(e->name,temp)) //not check NULL==e
				return insert(e->name,e);
			return false;
		}

		inline void remove(zEntry *e)
		{
			if(e)
			{
				LimitHash<const char *,zEntry *>::remove(e->name);
			}
		}

		inline zEntry * getEntryByName(const char * name) const
		{
			zEntry *ret = NULL;
			LimitHash<const char *,zEntry *>::find(name,ret);
			return ret;
		}
		inline zEntry * getEntryByName(const std::string name) const
		{
			return getEntryByName(name.c_str());
		}
};

/**
 *\brief 以name为key的指针容器，需要继承使用 
 */
class zMultiEntryName : public LimitHash<const char *,zEntry *>
{
	protected:

		inline bool push(zEntry * &e) //point ref
		{
			return insert(e->name,e);
		}

		inline void remove(zEntry * &e)
		{
			__gnu_cxx::pair<iter,iter> its = ets.equal_range(e->name);
			for(iter it = its.first;it != its.second;++it)
			{
				if(it->second == e)
				{
					ets.erase(it);
					return;
				}
			}
		}
		
		/**
		 * \brief 根据name查找数据，找到结果放入e中，r表示如果有多项匹配，是否随即选择
		 */
		inline bool find(const char * &name,zEntry * &e,const bool r=false) const
		{
			unsigned int rd = ets.cout(name);
			if(rd)
			{
				int mrd = 0,j = 0;
				if(r)
					mrd = zMisc::randBetween(0,rd-1);
				__gnu_cxx::pair<const_iter,const_iter> its = ets.equal_range(name);
				for(const_iter it = its.first;it != its.second && j < rd;++it,++j)
				{
					if(mrd == j)
					{
						e = it->second;
						return true;
					}
				}
			}
			return false;
		}
};

template <int i>
class zEntryNone
{
	protected:
		inline bool push(zEntry * &e) { return true; }
		inline void remove(zEntry * &e) { }
		inline void clear() { }
};

/**
 *\brief Entry处理接口，由zEntryManager::execEveryEntry 使用
 */
template <typename YourEntry>
struct execEntry
{
	virtual bool exec(YourEntry *entry) = 0;
	virtual ~execEntry() {}
};

/**
 *\brief Entry处理接口，由zEntryManager::removeEntry_if使用
 */
template <typename YourEntry>
struct removeEntry_Pred
{
	std::vector<YourEntry *> removed;
	virtual bool isIt(YourEntry *entry) = 0;
	virtual ~removeEntry_Pred() {}
};

/**
 *\brief Entry管理器接口，根据实际情况继承使用
 */
template <typename e1,typename e2=zEntryNone<1>,typename e3=zEntryNone<2> >
class zEntryManager : protected e1,protected e2,protected e3
{
	protected:
		inline bool addEntry(zEntry *e)
		{
			if(e1::push(e))
			{
				if(e2::push(e))	
				{
					if(e3::push(e))	
						return true;
					else
					{
						e2::remove(e);
						e1::remove(e);
					}
				}
				else
					e1::remove(e);
			}
			return false;
		}
		inline void removeEntry(zEntry *e)
		{
			e1::remove(e);
			e2::remove(e);
			e3::remove(e);
		}

		~zEntryManager() {}

		inline int size() const
		{
			return e1::size();	
		}
		inline bool empty() const
		{
			return e1::empty();
		}
		inline void clear()
		{
			e1::clear();
			e2::clear();
			e3::clear();
		}
		/**
		 * \brief 对每一个Entry处理，遇到一个返回false的立即终止
		 */
		template <typename YourEntry>
		inline bool execEveryEntry(execEntry<YourEntry> &eee)
		{
			typedef typename e1::iter my_iter;
			for(my_iter it=e1::ets.begin();it!=e1::ets.end();++it)
			{
				if(!eee.exec((YourEntry *)it->second))	
					return false;
			}
			return true;
		}
		/**
		 * \brief 删除满足条件的Entry
		 */
		template <typename YourEntry>
		inline void removeEntry_if(removeEntry_Pred<YourEntry> &pred)
		{
			typedef typename e1::iter my_iter;
			my_iter it = e1::ets.begin();
			while(it != e1::ets.end())
			{
				if(pred.isIt((YourEntry *)it->second))
				{
					pred.removed.push_back((YourEntry *)it->second);
				}
				++it;
			}
			for(unsigned int i=0;i<pred.removed.size();++i)
			{
				removeEntry(pred.removed.at(i));
			}
		}
};


#endif
